package com.waffle.batterywidget;

import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED;
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.BatteryManager;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;

/**
 * Define a simple widget that shows a battery meter. To build
 * an update we spawn a background {@link Service} to perform the API queries.
 */
public class BatteryWidget extends AppWidgetProvider {
    
    static final String LOG_TAG = BatteryWidget.class.getSimpleName();
    static final int SDK_VERSION = Integer.parseInt(android.os.Build.VERSION.SDK);
    static final String KEY_PREV_LEVEL = "KEY_PREV_LEVEL";
    static final String KEY_PREV_STATUS = "KEY_PREV_STATUS";
    static final String KEY_SCALE = "KEY_SCALE";
    static final String KEY_ACTIVE_IDS = "KEY_ACTIVE_IDS";
    private static final String EXTRA_NEW_WIDGET = "EXTRA_NEW_WIDGET";
    
	public static String PREFS_NAME="BATWIDG_PREFS";
	public static String KEY_LEVEL = "BATWIDG_LEVEL";
	public static String KEY_CHARGING = "BATWIDG_CHARGING";
	
	@Override
	public void onEnabled(Context context) {
  	    BatteryWidget.clearSettings(context);
		super.onEnabled(context);
	}
	
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // Special app widget delete handling added for bug in Android 1.5, as described at 
        // http://groups.google.com/group/android-developers/browse_thread/thread/365d1ed3aac30916?pli=1
        String action = intent.getAction();
        if (SDK_VERSION <= 3 && ACTION_APPWIDGET_DELETED.equals(action))
        {
            int appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
            if (appWidgetId != INVALID_APPWIDGET_ID)
            {
                this.onDeleted(context, new int[] { appWidgetId });
            }
        }
        else
        {
            super.onReceive(context, intent);
        }
    }
	
	@Override
	public void onDisabled(Context context) {
		super.onDisabled(context);
		try
		{
			context.stopService(new Intent(context, UpdateService.class));//unregisterReceiver(mBI);
		}catch(Exception e){Log.e(LOG_TAG,"",e);}
        BatteryWidget.clearSettings(context);
	}
	
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		super.onDeleted(context, appWidgetIds);
		try
		{
			context.stopService(new Intent(context, UpdateService.class));//if(mBI != null) context.unregisterReceiver(mBI);
		}catch(Exception e){Log.e(LOG_TAG,"",e);}
	}
	
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
        boolean isNewWidget = ActiveAppWidgetIdsManager.registerIds(context, appWidgetIds);
        // To prevent any ANR timeouts, we perform the update in a service
        Intent intent = new Intent(context, UpdateService.class);
        intent.putExtra(EXTRA_NEW_WIDGET, isNewWidget);
    	context.startService(intent);
    }
    
    private static void clearSettings(Context context) {
        ActiveAppWidgetIdsManager.clearActiveAppWidgetIds();
        if (context != null)
        {
            SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
            Editor editor = settings.edit();
            editor.remove(KEY_PREV_LEVEL);
            editor.remove(KEY_PREV_STATUS);
            editor.remove(KEY_LEVEL);
            editor.remove(KEY_CHARGING);
            editor.remove(KEY_SCALE);
            editor.remove(KEY_ACTIVE_IDS);
            editor.commit();
        }
    }
    
    public static class UpdateService extends Service {
        
    	BatteryInfo mBI = null;
    	
    	@Override
        public void onStart(Intent intent, int startId) {
			if(mBI == null)
	        {
	        	mBI = new BatteryInfo();
	        	IntentFilter mIntentFilter = new IntentFilter();
	            mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
	            registerReceiver(mBI, mIntentFilter);
	            // After registering mBI, another update is immediately processed.
	            // So, skip double update processing.
	            return;
	        }
        	
        	// Build the widget update for today
			boolean isNewWidget = intent.getBooleanExtra(EXTRA_NEW_WIDGET, false);
        	RemoteViews updateViews = buildUpdate(this, isNewWidget);
            if(updateViews != null)
            {
	            try
	            {
		            // Push update for this widget to the home screen
		            ComponentName thisWidget = new ComponentName(this, BatteryWidget.class);
		            if(thisWidget != null)
		            {
			            AppWidgetManager manager = AppWidgetManager.getInstance(this);
			            if(manager != null && updateViews != null)
			            {
			            	manager.updateAppWidget(thisWidget, updateViews);
			            }
		            }
		            
		            //stop the service, clear up memory, can't do this, need the Broadcast Receiver running
		            //stopSelf();
	            }catch(Exception e)
	            {
	            	Log.e(LOG_TAG, "", e);
	            }
            }
        }
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		try{
    			if(mBI != null) unregisterReceiver(mBI);
    		}catch(Exception e)
    		{Log.e(LOG_TAG, "", e);}
    	}
    	
        /**
         * Build a widget update to show the current Wiktionary
         * "Word of the day." Will block until the online API returns.
         */
        public RemoteViews buildUpdate(Context context, boolean isNewWidget) {           
            // Build an update that holds the updated widget contents
            RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
            try
            {
	            int level = 0;
	            boolean charging = false;
	            SharedPreferences settings = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
	            if(settings !=null)
	            {
                    int prevLevel = settings.getInt(KEY_PREV_LEVEL, -1);
                    int prevStatus = settings.getInt(KEY_PREV_STATUS, -1);
                    int currentLevel = settings.getInt(KEY_LEVEL, 0);
                    int currentStatus = settings.getInt(KEY_CHARGING, 0);
                    if (!isNewWidget && prevLevel > -1 && prevLevel == currentLevel && prevStatus == currentStatus)
                    {
                        return null;
                    }
                    Editor editor = settings.edit();
                    editor.putInt(KEY_PREV_LEVEL, currentLevel);
                    editor.putInt(KEY_PREV_STATUS, currentStatus);
                    editor.commit();
                    level = settings.getInt(KEY_LEVEL, 0);
	            	charging = (settings.getInt(KEY_CHARGING, BatteryManager.BATTERY_STATUS_UNKNOWN)==BatteryManager.BATTERY_STATUS_CHARGING);
	            }
	            else
	            {
	                return null;
	            }
	            
	            if(level>20)
	            {
		            updateViews.setViewVisibility(R.id.bar100, level>80?View.VISIBLE:View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar80, level>60?View.VISIBLE:View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar60, level>40?View.VISIBLE:View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar40, level>20?View.VISIBLE:View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar20, View.VISIBLE);
		            updateViews.setImageViewResource(R.id.bar20, R.drawable.bar_green);
		            
		            updateViews.setViewVisibility(R.id.batterytext, View.VISIBLE);
	            }else
	            {
		            updateViews.setViewVisibility(R.id.bar100, View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar80, View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar60, View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar40, View.INVISIBLE);
		            updateViews.setViewVisibility(R.id.bar20, View.VISIBLE);
		            updateViews.setImageViewResource(R.id.bar20, R.drawable.bar_red);
		            
		            updateViews.setViewVisibility(R.id.batterytext, View.VISIBLE);
	            }
	
	            updateViews.setViewVisibility(R.id.charging, charging?View.VISIBLE:View.INVISIBLE);
	            
	            int scale = settings.getInt(KEY_SCALE, 100);
	            if (scale <= 0) scale = 100;
	            int levelPercent = (100 * level) / scale;
	            String levelText = levelPercent==100?"100":levelPercent+"%"; //100% too wide
	            if(level == 0) levelText=" 0%";
	            updateViews.setTextViewText(R.id.batterytext, levelText);
	        }catch(Exception e)
	        {
	            Log.e(LOG_TAG, "", e);
	        }
            
//    		try
//    		{
//	            Intent defineIntent2 = new Intent(context,TranslucentBlurActivity.class);
//	            PendingIntent pendingIntent2 = PendingIntent.getActivity(context,0 /* no requestCode */, defineIntent2, 0 /* no flags */);
//	            updateViews.setOnClickPendingIntent(R.id.widget, pendingIntent2);
//    		}catch(Exception e)
//    		{
//    		    Log.e(LOG_TAG, "", e);
//    		}
            return updateViews;
        }
        
        @Override public IBinder onBind(Intent intent) {return null;}
    }
}